package org.jianfa.mq.seckill.service.impl;

import org.jianfa.mq.seckill.entity.po.OrderInfo;
import org.jianfa.mq.seckill.entity.po.SeckillOrder;
import org.jianfa.mq.seckill.entity.vo.GoodsVo;
import org.jianfa.mq.seckill.mapper.SeckillGoodsMapper;
import org.jianfa.mq.seckill.redis.GoodsKeyPrefix;
import org.jianfa.mq.seckill.redis.RedisService;
import org.jianfa.mq.seckill.redis.SeckillKeyPrefix;
import org.jianfa.mq.seckill.rocketmq.RocketMqProducer;
import org.jianfa.mq.seckill.rocketmq.SeckillMessage;
import org.jianfa.mq.seckill.service.GoodsService;
import org.jianfa.mq.seckill.service.OrderService;
import org.jianfa.mq.seckill.service.SeckillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class SeckillServiceImpl implements SeckillService {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RocketMqProducer rocketMqProducer;

    @Transactional
    public OrderInfo seckill(SeckillMessage seckillMessage) {
        long userId = seckillMessage.getUserId();
        long goodsId = seckillMessage.getGoodsId();

        //1. 减库存
        boolean reduceStock = goodsService.reduceStock(goodsId);
        if (!reduceStock) {
            setGoodsOver(goodsId);
            return null;
        }

        //2.生成订单
        GoodsVo goodsVo = seckillGoodsMapper.selectWithDetailByPrimaryKey(goodsId);
        OrderInfo orderInfo = orderService.createOrder(userId, goodsVo);

        //3.发送消息
        boolean sendDelayMessage = rocketMqProducer.sendDelayMessage(orderInfo);
        if (!sendDelayMessage) {
            throw new RuntimeException("发送延迟队列失败！");
        }

        //4. 减库存
        redisService.decr(GoodsKeyPrefix.seckillGoodsStockPrefix, "" + goodsId);

        return orderInfo;
    }

    public long getSeckillResult(Long userId, long goodsId) {
        SeckillOrder order = orderService.getSeckillOrderByUserIdAndGoodsId(userId, goodsId);
        if (order != null) {//秒杀成功
            return order.getOrderId();
        } else {
            boolean isOver = getGoodsOver(goodsId);
            if (isOver) {
                return -1;
            } else {
                return 0;
            }
        }
    }

    public boolean getGoodsOver(long goodsId) {
        return redisService.exists(SeckillKeyPrefix.isGoodsOver, "" + goodsId);
    }

    public void setGoodsOver(long goodsId) {
        redisService.set(SeckillKeyPrefix.isGoodsOver, "" + goodsId, true);
    }
}
